package com.csaba.connector.bha.com;

public class MD5
{
	private abstract class Fcore
	{

		abstract int a( int i, int j, int k );

		final MD5 b;

		private Fcore()
		{
			b = MD5.this;
		}

		Fcore( Fcore fcore )
		{
			this();
		}
	}

	public MD5()
	{
		e = new Fcore()
		{
			int a( int i, int j, int k )
			{
				return k ^ i & ( j ^ k );
			}
		};
		f = new Fcore()
		{
			int a( int i, int j, int k )
			{
				return j ^ k & ( i ^ j );
			}
		};
		g = new Fcore()
		{
			int a( int i, int j, int k )
			{
				return i ^ j ^ k;
			}
		};
		h = new Fcore()
		{
			int a( int i, int j, int k )
			{
				return j ^ ( i | ~k );
			}
		};
		a = new int[4];
		a[0] = 0x67452301;
		a[1] = 0xefcdab89;
		a[2] = 0x98badcfe;
		a[3] = 0x10325476;
		b = 0L;
		c = new byte[64];
		d = new int[16];
	}

	public void a( byte abyte0[], int i )
	{
		a(abyte0, 0, i);
	}

	public void a( byte abyte0[], int i, int j )
	{
		int l = j;
		int k = (int) b;
		b += l << 3;
		k = k >>> 3 & 0x3f;
		if ( k != 0 )
		{
			int i1 = k;
			k = 64 - k;
			if ( l < k )
			{
				System.arraycopy(abyte0, i, c, i1, l);
				return;
			}
			System.arraycopy(abyte0, i, c, i1, k);
			a();
			i += k;
			l -= k;
		}
		for ( ; l >= 64; l -= 64 )
		{
			System.arraycopy(abyte0, i, c, 0, 64);
			a();
			i += 64;
		}

		System.arraycopy(abyte0, i, c, 0, l);
	}

	public void a( byte abyte0[] )
	{
		int i = (int) ( b >>> 3 & 63L );
		int j = i;
		c[j++] = -128;
		i = 63 - i;
		if ( i < 8 )
		{
			b(c, j, i);
			a();
			b(c, 0, 56);
		}
		else
		{
			b(c, j, i - 8);
		}
		int k = (int) b;
		int l = (int) ( b >>> 32 );
		c(c, 56, k);
		c(c, 60, l);
		a();
		c(abyte0, 0, a[0]);
		c(abyte0, 4, a[1]);
		c(abyte0, 8, a[2]);
		c(abyte0, 12, a[3]);
		c(c);
		a(a);
		b = 0L;
		a(d);
	}

	private void c( byte abyte0[] )
	{
		b(abyte0, 0, abyte0.length);
	}

	private void b( byte abyte0[], int i, int j )
	{
		a(abyte0, (byte) 0, i, j);
	}

	private void a( byte abyte0[], byte byte0, int i, int j )
	{
		int l = i + j;
		for ( int k = i; k < l; k++ )
			abyte0[k] = byte0;

	}

	private void a( int ai[] )
	{
		a(ai, 0, ai.length);
	}

	private void a( int ai[], int i, int j )
	{
		a(ai, 0, i, j);
	}

	private void a( int ai[], int i, int j, int k )
	{
		int i1 = j + k;
		for ( int l = j; l < i1; l++ )
			ai[l] = i;

	}

	private int a( Fcore fcore, int i, int j, int k, int l, int i1, int j1 )
	{
		i += fcore.a(j, k, l) + i1;
		i = i << j1 | i >>> 32 - j1;
		i += j;
		return i;
	}

	private void a()
	{
		int ai[] = new int[16];
		for ( int i = 0; i < 16; i++ )
			ai[i] = b(c, 4 * i);

		int j = a[0];
		int k = a[1];
		int l = a[2];
		int i1 = a[3];
		j = a(e, j, k, l, i1, ai[0] + 0xd76aa478, 7);
		i1 = a(e, i1, j, k, l, ai[1] + 0xe8c7b756, 12);
		l = a(e, l, i1, j, k, ai[2] + 0x242070db, 17);
		k = a(e, k, l, i1, j, ai[3] + 0xc1bdceee, 22);
		j = a(e, j, k, l, i1, ai[4] + 0xf57c0faf, 7);
		i1 = a(e, i1, j, k, l, ai[5] + 0x4787c62a, 12);
		l = a(e, l, i1, j, k, ai[6] + 0xa8304613, 17);
		k = a(e, k, l, i1, j, ai[7] + 0xfd469501, 22);
		j = a(e, j, k, l, i1, ai[8] + 0x698098d8, 7);
		i1 = a(e, i1, j, k, l, ai[9] + 0x8b44f7af, 12);
		l = a(e, l, i1, j, k, ai[10] + -42063, 17);
		k = a(e, k, l, i1, j, ai[11] + 0x895cd7be, 22);
		j = a(e, j, k, l, i1, ai[12] + 0x6b901122, 7);
		i1 = a(e, i1, j, k, l, ai[13] + 0xfd987193, 12);
		l = a(e, l, i1, j, k, ai[14] + 0xa679438e, 17);
		k = a(e, k, l, i1, j, ai[15] + 0x49b40821, 22);
		j = a(f, j, k, l, i1, ai[1] + 0xf61e2562, 5);
		i1 = a(f, i1, j, k, l, ai[6] + 0xc040b340, 9);
		l = a(f, l, i1, j, k, ai[11] + 0x265e5a51, 14);
		k = a(f, k, l, i1, j, ai[0] + 0xe9b6c7aa, 20);
		j = a(f, j, k, l, i1, ai[5] + 0xd62f105d, 5);
		i1 = a(f, i1, j, k, l, ai[10] + 0x2441453, 9);
		l = a(f, l, i1, j, k, ai[15] + 0xd8a1e681, 14);
		k = a(f, k, l, i1, j, ai[4] + 0xe7d3fbc8, 20);
		j = a(f, j, k, l, i1, ai[9] + 0x21e1cde6, 5);
		i1 = a(f, i1, j, k, l, ai[14] + 0xc33707d6, 9);
		l = a(f, l, i1, j, k, ai[3] + 0xf4d50d87, 14);
		k = a(f, k, l, i1, j, ai[8] + 0x455a14ed, 20);
		j = a(f, j, k, l, i1, ai[13] + 0xa9e3e905, 5);
		i1 = a(f, i1, j, k, l, ai[2] + 0xfcefa3f8, 9);
		l = a(f, l, i1, j, k, ai[7] + 0x676f02d9, 14);
		k = a(f, k, l, i1, j, ai[12] + 0x8d2a4c8a, 20);
		j = a(g, j, k, l, i1, ai[5] + 0xfffa3942, 4);
		i1 = a(g, i1, j, k, l, ai[8] + 0x8771f681, 11);
		l = a(g, l, i1, j, k, ai[11] + 0x6d9d6122, 16);
		k = a(g, k, l, i1, j, ai[14] + 0xfde5380c, 23);
		j = a(g, j, k, l, i1, ai[1] + 0xa4beea44, 4);
		i1 = a(g, i1, j, k, l, ai[4] + 0x4bdecfa9, 11);
		l = a(g, l, i1, j, k, ai[7] + 0xf6bb4b60, 16);
		k = a(g, k, l, i1, j, ai[10] + 0xbebfbc70, 23);
		j = a(g, j, k, l, i1, ai[13] + 0x289b7ec6, 4);
		i1 = a(g, i1, j, k, l, ai[0] + 0xeaa127fa, 11);
		l = a(g, l, i1, j, k, ai[3] + 0xd4ef3085, 16);
		k = a(g, k, l, i1, j, ai[6] + 0x4881d05, 23);
		j = a(g, j, k, l, i1, ai[9] + 0xd9d4d039, 4);
		i1 = a(g, i1, j, k, l, ai[12] + 0xe6db99e5, 11);
		l = a(g, l, i1, j, k, ai[15] + 0x1fa27cf8, 16);
		k = a(g, k, l, i1, j, ai[2] + 0xc4ac5665, 23);
		j = a(h, j, k, l, i1, ai[0] + 0xf4292244, 6);
		i1 = a(h, i1, j, k, l, ai[7] + 0x432aff97, 10);
		l = a(h, l, i1, j, k, ai[14] + 0xab9423a7, 15);
		k = a(h, k, l, i1, j, ai[5] + 0xfc93a039, 21);
		j = a(h, j, k, l, i1, ai[12] + 0x655b59c3, 6);
		i1 = a(h, i1, j, k, l, ai[3] + 0x8f0ccc92, 10);
		l = a(h, l, i1, j, k, ai[10] + 0xffeff47d, 15);
		k = a(h, k, l, i1, j, ai[1] + 0x85845dd1, 21);
		j = a(h, j, k, l, i1, ai[8] + 0x6fa87e4f, 6);
		i1 = a(h, i1, j, k, l, ai[15] + 0xfe2ce6e0, 10);
		l = a(h, l, i1, j, k, ai[6] + 0xa3014314, 15);
		k = a(h, k, l, i1, j, ai[13] + 0x4e0811a1, 21);
		j = a(h, j, k, l, i1, ai[4] + 0xf7537e82, 6);
		i1 = a(h, i1, j, k, l, ai[11] + 0xbd3af235, 10);
		l = a(h, l, i1, j, k, ai[2] + 0x2ad7d2bb, 15);
		k = a(h, k, l, i1, j, ai[9] + 0xeb86d391, 21);
		a[0] += j;
		a[1] += k;
		a[2] += l;
		a[3] += i1;
	}

	private int b( byte abyte0[], int i )
	{
		return abyte0[i + 0] & 0xff | ( abyte0[i + 1] & 0xff ) << 8 | ( abyte0[i + 2] & 0xff ) << 16
				| ( abyte0[i + 3] & 0xff ) << 24;
	}

	private void c( byte abyte0[], int i, int j )
	{
		abyte0[i + 0] = (byte) ( j & 0xff );
		abyte0[i + 1] = (byte) ( j >> 8 & 0xff );
		abyte0[i + 2] = (byte) ( j >> 16 & 0xff );
		abyte0[i + 3] = (byte) ( j >> 24 & 0xff );
	}

	//NAME: getHashValue
	public static byte[] getHashValue( byte abyte0[] )
	{
		MD5 md5 = new MD5();
		byte abyte1[] = new byte[16];
		md5.a(abyte0, abyte0.length);
		md5.a(abyte1);
		return abyte1;
	}

	int a[];
	long b;
	byte c[];
	int d[];
	private Fcore e;
	private Fcore f;
	private Fcore g;
	private Fcore h;
}
